var net = require('net');
var zlib = require('zlib');
var events = require("events");

var debug = require("./debug").tcpClient;

exports.Client = function (ip, port, onConnected, onReceive) {
    var eve = new events.EventEmitter();
    eve.on('data', function (tid, content) {
        if (debug.recvData) {
            console.log('[' + new Date().toLocaleTimeString() + ']' + 'tcp recv:' + '[' + tid + ']' + content);
        }
    });

    var socket = net.connect(port, ip, function () {
        console.log('tcp connected');
        isOpen = true;
        eve.emit('connect')
    });
    var isOpen = false;

    socket.on('data', function (data) {
        for (var i = 0; i < data.length; ) {
            var head = data.readUInt32LE(i);
            var isCompress = head >> 31 != 0;
            var tid = head & 0xff;
            var length = (head & 0X7FFFFFF0) >> 8;

            if (isCompress) {
                var buf = new Buffer(length);
                data.copy(buf, 0, i + 4, i + 4 + length);
                readCompressData(buf, tid, onReceive);
            } else {
                var content = data.toString('utf8', i + 4, i + 4 + length);
                eve.emit('data', tid, content);
            }
            i += 4 + length;
        }
    });

    socket.on('close', function () {
        console.log('tcp closed');
        isOpen = false;
        eve.emit('close');
    });

    this.on = function (_event, _listenter) {
        eve.on(_event, _listenter);
        return this;
    };

    this.send = function (tid, content) {
        if (isOpen) {

            var contentLength = Buffer.byteLength(content);
            var buf = new Buffer(4 + contentLength);
            buf.writeUInt8(tid, 0);
            buf.writeUInt8(contentLength, 1);
            buf.writeUInt8(0, 2);
            buf.write(content, 4);
            socket.write(buf, 'utf8', function () {

                if (debug.sendData) {
                    console.log('[' + new Date().toLocaleTimeString() + ']' + 'tcp send:' + '[' + tid + ']' + content);
                }
            });
        }
    };

    this.close = function () {
        console.log('tcp closing');
        isOpen = false;
        socket.destroy();
    };
}

function readCompressData(buf, tid, callback) {
    zlib.unzip(buf, function (err, buffer) {
        if (!err) {
            var content = buffer.toString();
            callback(tid, content);
        } else {
            console.log(err);
        }
    });
}